Your first game

M abstracts the idea of a game. In M, every game is described by a set of entities and a set of systems. Entities hold all the data and systems declare the code to interact with that data.

Shoot them up. We will use an iterative approach were we keep adding features one by one. A feature includes data and interaction, so we must edit the entities and systems that exist in the world to add a new feature.

But first, let's extract all the features ww desire in the core game loop of our game.

Feature extraction

Note that the words used are consciously vague, as no art direction is involved for now. The character could be a car, a spaceship, a superhero or a dolphin. The hazards could be asteroids, tanks or chickens, etc.

Rendering the character

The rendering is done implicitly. Every entity that has some visual data is supposed to be rendered - if it is in the view of the camera -. So all we need to do is to provide visual data to the entities we want to render. We will use 3D art for this game. So every visual element will need a mesh and a material.

"character" { position 0 0 0, mesh "spaceship", material "shiny" }

Similarly for the hazards:

"hazard" { mesh "asteroid", material "rock" }

Now don't expect the engine to generate the specified art for you. Maybe in future versions it will find and download certain public domain assets, but for now, it will generate some placeholder meshes and materials that artists can replace with their creations.

Controlling the character

control
{
    foreach a
    {
        a.velocity = a.motionVector * a.speed
    }
}

Shooting projectiles

    shoot:
    for all entity a with gunTriggered
    {
        projectile = create(a.projectile)
        projectile.position = a.position + a.gunOffset
    }
    projectile { position 0 0 0, mesh bullet, material deadly, velocity 0 10 0 }
    character { velocity 0 0, motion gamepad left stick, speed 5 }

Move hazards

Hazards will be moved by the physics, all we need to do is to add mass

    hazard { mass 1 }

Create hazards over time

    createHazards:
    for all entity a with spawnRateTimeout
    {
        spawned = create(a.spawn)
        spawned.position = join(random(a.positionRangeX),random(a.positionRangeY))
    }
    spawner { spawn hazard, positionRangeX -50 50, positionRangeY 50 60 }

Destroy hazards with bullets

    destroy:
    for all entity a with enterCollision
    {
        if has(a.first, forceDestruction)
        {
            destroy(a.second)
            destroy(a.first)
        }
    }
    projectile { radius 0.5, forceDestruction }

~~~ text
    hazard { extent 1 1 1, forceDestruction }

Reset when character dies

    die:
    for all entity a
    {
        for all entity b with essentialCharacter
        {
            count += a.worth
        }
        if count = a.restartAmount
        {
            for all entity c
            {
                destroy(c)
            }
            create(a.scene)
        }
    }